<?php
namespace app\admin\controller;

use app\admin\Diluma;
use app\admin\model\Menu;
use app\admin\model\Menu as menuModel;
use app\admin\service\MenuService;
use app\admin\service\RoleService;
use app\admin\validate\MenuValidate;
use think\facade\Db;
use think\facade\View;
use think\Request;

/**
 * 系统菜单控制器
 * Class SystemMenu
 * @package app\admin\controller
 */
class SystemMenu extends Diluma
{
    public function index()
    {
        return View::fetch();
    }

    /**
     * 列表数据
     * @return \think\response\Json
     */
    public function getList()
    {
        $model = new menuModel();
        $list = $model->getMenuList();
        return json(['code'=>0, 'data'=>$list]);
    }

    /**
     * 新增
     * @return mixed|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function insert(){
        $model = new menuModel();
        if($this->request->isPost()) {
            $post = $this->request->post();
            validate(MenuValidate::class)->scene('insert')->checkData($post['field']);
            $item = $model->where('name', $post['field']['name'])->find();
            if (!empty($item)) {
                return json(["code" => 1, 'msg' => "{$post['field']['name']} 已存在，请勿重复添加"]);
            }
            if($model->save($post['field'])) {
                return json(["code" => 0, 'msg' => '添加成功']);
            } else {
                return json(["code" => 1, 'msg' => '更新失败，请重试']);
            }
        } else {
            $pid = $this->request->param('pid');
            if($pid) {
                view::assign('pid', $pid);
            }
            $menus = $model->getMenuList();
            view::assign('sort', $model->getSort());
            view::assign('menus',$menus);
            return view::fetch();
        }
    }

    /**
     * 修改菜单
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function edit()
    {
        $model = new menuModel();
        if($this->request->isPost()) {
            $id = $this->request->param('field.id', 0, 'intval');
            if(!$id){
                return json(['code'=>1, 'msg'=>'id不正确']);
            }
            $post = $this->request->post();
            validate(MenuValidate::class)->scene('update')->checkData($post['field']);
            $item = $model->find($id);
            if(empty($item)) {
                return json(['code'=>1, 'msg'=>'记录不存在']);
            }
            // 如果关闭默认展开，给默认值0
            if(empty($post['field']['is_open'])) {
                $post['field']['is_open'] = 0;
            }

            if(false == $item->save($post['field'])) {
                return json(['code'=>1, 'msg'=>'修改失败']);
            } else {
                return json(['code'=>0, 'msg'=>'修改系统菜单信息成功']);
            }
        } else{
            $id = $this->request->param('id', 0, 'intval');
            if($id <= 0){
                return josn(['code'=>1, 'msg'=>'参数异常']);
            }
            $menu = $model->where('id',$id)->find();
            $list = $model->getMenuList();
            View::assign('menus',$list);
            View::assign('menu',$menu);
            return View::fetch();
        }
    }

    /**
     * 删除
     * @return \think\response\Json|void
     */
    public function delete()
    {
    	if($this->request->isPost()) {
    		$id = $this->request->post('id', 0, 'intval');
            $model = new menuModel();
            $item = $model->find($id);
            if (!$item) {
                return json(['code'=>1, 'msg'=>'菜单不存在，删除失败']);
            }
            $childMenu = $model->where('pid', $id)->select();
    		if($childMenu->isEmpty()) {
    		    if(false === $item->delete()) {
                    return json(['code'=>1, 'msg'=>'删除失败']);
                } else {
                    return json(['code'=>0, 'msg'=>'删除成功']);
                }
            } else {
                return json(['code'=>1, 'msg'=>'该系统菜单下还有子系统菜单，不能删除']);
            }
    	}
    }

    /**
     * 系统菜单排序
     * @param Request $request
     * @return mixed
     * @throws \think\db\exception\DbException
     */
    public function sort(Request $request): mixed
    {
        if($request->isPost()) {
            $post = $request->post();
            if(false == Db::name('admin_menu')->where('id',$post['id'])->update(['sort'=>$post['sort']])) {
                return json(['code'=>1, 'msg'=>'更新失败']);
            } else {
                return json(['code'=>0, 'msg'=>'更新成功']);
            }
        }
    }

    /**
     * 系统菜单排序
     * @param ids|array
     * @return code|msg
     */
    public function orders()
    {
        if($this->request->isPost()) {
            $post = $this->request->post();
            $i = 0;
            foreach ($post['id'] as $k => $val) {
                $order = Db::name('menu')->where('id',$val)->value('sort');
                if($order != $post['sort'][$k]) {
                    if(false == Db::name('menu')->where('id',$val)->update(['sort'=>$post['sort'][$k]])) {
                        return json(['code'=>0, 'msg'=>'更新失败']);
                    } else {
                        $i++;
                    }
                }
            }
            operate_log(0,'更新排序系统菜单ids：:'.json_encode($post,320));//写入日志
            return json(['code'=>1, 'msg'=>'成功更新'.$i.'个数据']);
        }
    }

    /**
     * 获取系统菜单
     * @return \think\response\Json
     */
    public function getSystemMenu()
    {
        $service = new MenuService();
        $items = $service->getSystemMenu();
        return json(['code'=>0, 'data'=>$items]);
    }

    /**
     * 获取系统选中菜单
     * @return \think\response\Json
     */
    public function getSystemMenuByChecked()
    {
        $roleId = $this->request->param('role_id');
        $roleService = new RoleService();
        $item = $roleService->getOneBy($roleId);

        $menuService = new MenuService();
        $model = new menuModel();
        $menuItems = $model->where("status", "=", 1)
            ->field(['id','name as title','pid'])
            ->where('is_display', 1)
            ->order(['sort'=>'desc','create_time'=>'asc'])
            ->select()
            ->toArray();
        if ($item->permission_ids) {
            $menuItems = $menuService->_formatSystemMenuByChecked(explode(',', $item->permission_ids), $menuItems);
        } else {
            $menuItems = (new MenuService())->_formatSystemMenu($menuItems);
        }

        return json(['code'=>0, 'data'=>$menuItems]);
    }

    /**
     * 格式化选中权限
     * @param $permissionIds
     * @param $menuItems
     * @return array
     */
    public function _formatMenu($permissionIds, $menuItems){
        if (empty($menuItems)) {
            return [];
        }
        foreach ($menuItems as &$item) {
            if (empty($item['children'])) {
                if (in_array($item['id'], $permissionIds) && $item['pid'] == 0) {
                    $item['checked'] = true;
                }
            } else {
                foreach ($item['children'] as &$child) {
                    if (in_array($child['id'], $permissionIds) && in_array($child['pid'], $permissionIds) && empty($child['children'])) {
                        $child['checked'] = true;
                    } else{
                        if (!empty($child['children'])) {
                            foreach ($child['children'] as &$son) {
                                if (in_array($son['id'], $permissionIds) && in_array($son['pid'], $permissionIds) && empty($son['children'])) {
                                    $son['checked'] = true;
                                }
                            }
                        }

                    }
                }
            }
        }

        return $menuItems;
    }
}
